package com.sample.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.URL;
import java.util.Currency;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by leo.na on 21/03/2017.
 */
@Service
public class YahooExchangeService {

    private static final Logger log = LoggerFactory.getLogger(YahooExchangeService.class);

    private static final Map<String, Currency> availableCurrencies = Currency.getAvailableCurrencies().stream().collect(Collectors.toMap(Currency::getCurrencyCode, c -> c));

    public BigDecimal getLiveRate(Currency from, Currency to) {
        BufferedReader reader = null;
        InputStreamReader isReader = null;
        InputStream is = null;
        try {
            // i.e. http://quote.yahoo.com/d/quotes.csv?f=l1&s=AUDNZD=X
            URL url = new URL("http://quote.yahoo.com/d/quotes.csv?f=l1&s=" + from + to + "=X");
            is = url.openStream();
            isReader = new InputStreamReader(is);
            reader = new BufferedReader(isReader);
            String line = reader.readLine();
            if (line != null && line.length() > 0) {
                BigDecimal rate = new BigDecimal(line);
                log.info("Yahoo exchange rate - [" + from + "/" + to + " = " + rate + "] ");
                return rate;
            }
        } catch (IOException | NumberFormatException e) {
            log.error("Failed to get exchange rate [" + from + "/" + to + "] via Yahoo");
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.info(e.getMessage(), e);
                }
            }
            if (isReader != null) {
                try {
                    isReader.close();
                } catch (IOException e) {
                    log.info(e.getMessage(), e);
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    log.info(e.getMessage(), e);
                }
            }
        }

        return null;
    }

    public BigDecimal getCachedRate(Currency from, Currency to) {
        // todo: cached rates per day or per hour
        return null;
    }

    public static Currency getCurrencyByCode(String code) {
        return availableCurrencies.get(code.toUpperCase());
    }

}
